TypeScript has become the de facto standard for professional JavaScript development. If you can write JavaScript, you're already 70% of the way to TypeScript. This guide covers the essential concepts with practical examples.

1. Why TypeScript?

  • Catch bugs at compile time — not at runtime in production
  • Better IDE support — autocomplete, refactoring, navigation
  • Self-documenting code — types serve as documentation
  • Safer refactoring — the compiler catches missed changes

2. Basic Types

// Primitives
let name: string = "Alice";
let age: number = 28;
let isActive: boolean = true;

// Arrays
let scores: number[] = [95, 88, 72];
let names: Array<string> = ["Alice", "Bob"];

// Objects
let user: { name: string; age: number; email?: string } = {
  name: "Alice",
  age: 28
};

// Union types
let id: string | number = "abc123";
id = 42; // Also valid

// Literal types
let status: "active" | "inactive" | "pending" = "active";

// Type assertion
const input = document.getElementById("search") as HTMLInputElement;

3. Interfaces & Type Aliases

// Interface - extensible, great for objects
interface User {
  id: number;
  name: string;
  email: string;
  role: "admin" | "user";
  createdAt: Date;
}

// Extension
interface AdminUser extends User {
  permissions: string[];
}

// Type alias - flexible, great for unions
type ApiResponse<T> = {
  data: T;
  status: number;
  message: string;
};

// Usage
const response: ApiResponse<User[]> = {
  data: [{ id: 1, name: "Alice", email: "a@b.com", role: "admin", createdAt: new Date() }],
  status: 200,
  message: "Success"
};
Ad

4. Generics

// Generic function
function firstElement<T>(arr: T[]): T | undefined {
  return arr[0];
}

const num = firstElement([1, 2, 3]);     // type: number
const str = firstElement(["a", "b"]);    // type: string

// Generic with constraints
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user = { name: "Alice", age: 28 };
getProperty(user, "name");  // ✅ "Alice"
// getProperty(user, "foo"); // ❌ Compile error

5. Utility Types

interface User {
  id: number;
  name: string;
  email: string;
  password: string;
}

// Partial - all properties optional
type UpdateUser = Partial<User>;

// Pick - select specific properties
type PublicUser = Pick<User, "id" | "name" | "email">;

// Omit - exclude properties
type UserWithoutPassword = Omit<User, "password">;

// Required - all properties required
type RequiredUser = Required<Partial<User>>;

// Record - typed key-value maps
type UserRoles = Record<string, "admin" | "user" | "guest">;

6. Pro Tips

  • Start with strict: true in tsconfig.json
  • Prefer unknown over any when type is uncertain
  • Use discriminated unions for complex state management
  • Leverage as const for literal type inference
  • Use satisfies operator for type checking without widening

TypeScript is not just "JavaScript with types" — it's a productivity superpower. Start by adding .ts extensions to your files and gradually add type annotations. The compiler will guide you.